package janino.resource;

import j2me.util.collections.ArrayList;
import j2me.util.collections.Arrays;
import j2me.util.collections.Iterator;
import j2me.util.collections.List;
import com.sun.midp.io.j2me.storage.File;
import janino.compilador.LazyMultiResourceFinder;
import janino.iterator.TransformingIterator;
import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;

/**
 * A {@link org.codehaus.janino.util.resource.ResourceFinder} that finds its
 * resources along a "path" consisting of JAR file names, ZIP file names, and
 * directory names.
 *
 * @see org.codehaus.janino.util.resource.ZipFileResourceFinder
 * @see org.codehaus.janino.util.resource.DirectoryResourceFinder
 */
public class PathResourceFinder extends LazyMultiResourceFinder {

    /**
     * @param entries The entries of the "path"
     */
    public PathResourceFinder(final FileConnection[] entries) {
        super(PathResourceFinder.createIterator(Arrays.asList(entries).iterator()));
    }

    /**
     * @param entries The entries of the "path" (type must be {@link File})
     */
    public PathResourceFinder(Iterator entries) {
        super(entries);
    }

    /**
     * @param path A java-like path, i.e. a "path separator"-separated list of
     * entries.
     */
    public PathResourceFinder(String path) throws IOException {
        this(PathResourceFinder.parsePath(path));
    }

    private static Iterator createIterator(final Iterator entries) {
        return new TransformingIterator(entries) {

            protected Object transform(Object o) {
                return PathResourceFinder.createResourceFinder((FileConnection) o);
            }
        };
    }

    /**
     * Break a given string up by the system-dependent path-separator character
     * (on UNIX systems, this character is ':'; on Microsoft Windows systems it
     * is ';'). Empty components are ignored. <p> UNIX Examples: <dl> <dt>A:B:C
     * <dd>A, B, C <dt>::B: <dd>B <dt>:A <dd>A <dt>(Empty string) <dd>(Zero
     * components) </dl>
     *
     * @see File#pathSeparatorChar
     */
    public static FileConnection[] parsePath(String s) throws IOException {
        int from = 0;

        List l = new ArrayList(); // File
        
        for (;;) {
            int to = s.indexOf(";", from);

            if (to == -1) {
                if (from != s.length()) {
                    String url = s.substring(from);
                    l.add((FileConnection) Connector.open(url));
                }
                break;
            }

            if (to != from) {
                l.add((FileConnection) Connector.open(s.substring(from, to)));
            }

            from = to + 1;
        }
     
        return (FileConnection[]) l.toArray(new FileConnection[l.size()]);
    }

    /**
     * A factory method that creates a Java classpath-style ResourceFinder as
     * follows: <table> <tr><th><code>entry</code></th><th>Returned {@link ResourceFinder}</th></tr>
     * <tr><td>"*.jar" file</td><td>{@link ZipFileResourceFinder}</td></tr>
     * <tr><td>"*.zip" file</td><td>{@link ZipFileResourceFinder}</td></tr> <tr><td>directory</td><td>{@link DirectoryResourceFinder}</td></tr>
     * <tr><td>any other</td><td>A {@link ResourceFinder} that never finds a
     * resource</td></tr> </table>
     *
     * @return a valid {@link ResourceFinder}
     */
    private static ResourceFinder createResourceFinder(final FileConnection entry) {

        // ZIP file or JAR file.
//        if (
//            (entry.getName().endsWith(".jar") || entry.getName().endsWith(".zip")) &&
//            entry.isFile()
//        ) {
//            try {
//                return new ZipFileResourceFinder(new ZipFile(entry));
//            } catch (IOException e) {
//                return ResourceFinder.EMPTY_RESOURCE_FINDER;
//            }
//        }

        // Directory.
        if (entry != null && entry.isDirectory()) {
            return new DirectoryResourceFinder(entry.getURL());
        }

        // Invalid entry.
        return ResourceFinder.EMPTY_RESOURCE_FINDER;
    }
}
